import { ref, computed } from 'vue'
import { ethers } from 'ethers'
import { useWeb3 } from './useWeb3'
import { handleWeb3Error } from '../utils/error'
import { CONTRACT_ADDRESSES } from '../contracts/config'
import { ABIS } from '../contracts/abi'

export function useContract(contractName, address) {
  const { provider, signer, isConnected } = useWeb3()

  // 确保在合约初始化之前连接已成功
  if (!isConnected.value) {
    console.error('合约未连接，无法初始化');
    return; 
  }

  const isLoading = ref(false)
  const contract = ref(null)

  // 初始化合约
  function init() {
    if (!isConnected.value) {
      throw new Error('合约未连接')
    }

    try {
      // 获取合约地址
      const contractAddress = address || CONTRACT_ADDRESSES.IPFS[contractName]
      if (!contractAddress) {
        throw new Error(`找不到合约地址: ${contractName}`)
      }

      // 获取合约 ABI
      const abi = ABIS[contractName]
      if (!abi) {
        throw new Error(`找不到合约 ABI: ${contractName}`)
      }

      // 创建合约实例
      contract.value = new ethers.Contract(contractAddress, abi, signer.value || provider.value)
      console.log('合约实例:', contract.value)
    } catch (error) {
      handleWeb3Error(error)
      throw error
    }
  }

  // 读取合约数据
  async function read(method, ...args) {
    if (!contract.value) {
      throw new Error('合约未连接')
    }

    try {
      isLoading.value = true
      return await contract.value[method](...args)
    } catch (error) {
      handleWeb3Error(error)
      throw error
    } finally {
      isLoading.value = false
    }
  }

  // 写入合约数据
  async function write(method, ...args) {
    if (!contract.value) {
      throw new Error('合约未连接')
    }
    if (!signer.value) {
      throw new Error('请先连接钱包')
    }

    try {
      isLoading.value = true
      const tx = await contract.value[method](...args)
      await tx.wait()
      return tx
    } catch (error) {
      handleWeb3Error(error)
      throw error
    } finally {
      isLoading.value = false
    }
  }

  // 监听合约事件
  function on(eventName, callback) {
    if (!contract.value) return
    contract.value.on(eventName, callback)
  }

  // 取消监听合约事件
  function off(eventName, callback) {
    if (!contract.value) return
    contract.value.off(eventName, callback)
  }

  return {
    contract,
    isLoading,
    init,
    read,
    write,
    on,
    off
  }
}
